﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Linq.Expressions;

namespace CH.Study.ConsoleApp.ExpressionTree
{


    public class QuerySpecification<T> where T : BaseEntity
    {
        public Expression<Func<T, bool>> WhereExp { get; set; }
        public QuerySpecification()
        {
   
        }
        public QuerySpecification<T> And(Expression<Func<T, bool>> exp)
        {
            if (WhereExp == null)
            {
                this.WhereExp = exp;
            }
            else
            {
                //1、这种写法可以创建表达式树 但是不能创建表达式树委托执行
                this.WhereExp = Expression.Lambda<Func<T, bool>>(Expression.And(this.WhereExp.Body, exp.Body), this.WhereExp.Parameters);


                //2、这种写法可以创建表达式树 可以创建表达式树委托执行
                //this.WhereExp = Expression.Lambda<Func<T, bool>>(Expression.And(this.WhereExp.Body, Expression.Invoke(exp, this.WhereExp.Parameters.Cast<Expression>())), this.WhereExp.Parameters);


                //3、这种写法可以创建表达式树 可以创建表达式树委托执行
                //Expression.Invoke(exp, this.WhereExp.Parameters.Cast<Expression>()) 调用一个委托
                //this.WhereExp.Parameters.Cast<Expression>() 是要传入的参数
                //var andExp = Expression.And(Expression.Invoke(this.WhereExp,this.WhereExp.Parameters), Expression.Invoke(exp, this.WhereExp.Parameters));
                //this.WhereExp = Expression.Lambda<Func<T, bool>>(andExp, this.WhereExp.Parameters);
            }
            return this;
        }
        public QuerySpecification<T> Or(Expression<Func<T, bool>> exp)
        {

            if (WhereExp == null)
            {
                this.WhereExp = exp;
            }
            else
            {


                //1、这种写法可以创建表达式树 但是不能创建表达式树委托执行
                this.WhereExp = Expression.Lambda<Func<T, bool>>(Expression.Or(this.WhereExp.Body, exp.Body), this.WhereExp.Parameters);


                //2、这种写法可以创建表达式树 可以创建表达式树委托执行
                //this.WhereExp = Expression.Lambda<Func<T, bool>>(Expression.Or(this.WhereExp.Body, Expression.Invoke(exp, this.WhereExp.Parameters.Cast<Expression>())), this.WhereExp.Parameters);


                //3、这种写法可以创建表达式树 可以创建表达式树委托执行
                //Expression.Invoke(exp, this.WhereExp.Parameters.Cast<Expression>()) 调用一个委托
                //this.WhereExp.Parameters.Cast<Expression>() 是要传入的参数
                //var andExp = Expression.Or(Expression.Invoke(this.WhereExp,this.WhereExp.Parameters), Expression.Invoke(exp, this.WhereExp.Parameters));
                //this.WhereExp = Expression.Lambda<Func<T, bool>>(andExp, this.WhereExp.Parameters);






            }
            return this;
        }



    }
}
